package impl

import (
	"adam2/internal/properties"
	serviceHelper "adam2/internal/service/helper"
	"anubis-framework/pkg/io"
)

type Robot7StockTransactRecordServiceImpl struct {
	*BaseServiceImpl
}

// 获取service的实现类
func GetRobot7StockTransactRecordServiceImpl() *Robot7StockTransactRecordServiceImpl {
	return &Robot7StockTransactRecordServiceImpl{GetBaseServiceImpl()}
}

// 执行根据bias来确定牛熊线的算法
func (_robot7StockTransactRecordServiceImpl *Robot7StockTransactRecordServiceImpl) DoBuyAndSellByBeginDateAndEndDate_Bias() error {
	io.Infoln("开始执行根据bias来确定牛熊线的算法")

	var dateArray []string
	var err error
	dateArray, err = _robot7StockTransactRecordServiceImpl._stockTransactionDataAllDaoImpl.GetDistinctDateBetweenDateOrderByDateAsc(properties.Robot7Properties_.BeginDate, properties.Robot7Properties_.EndDate)
	if err != nil {
		io.Fatalf("调用GetDistinctDateBetweenDateOrderByDateAsc方法时报错：%s", err.Error())
		return err
	}

	for _, currentDate := range dateArray {
		io.Infoln("当前的交易日期：%s", currentDate)

		/*************************************** 卖股票 ***********************************************/
		// 更新robot7_account表
		_robot7StockTransactRecordServiceImpl._robot7AccountDaoImpl.UpdateRobotAccountBeforeSellOrBuy_all(currentDate)
		// 卖股票
		_robot7StockTransactRecordServiceImpl._robot7StockTransactRecordDaoImpl.SellOrBuy_all(currentDate, properties.Robot7Properties_.MandatoryStopLoss, properties.Robot7Properties_.MandatoryStopLossRate)
		// 根据当日卖出股票的收盘价，在卖股票之后，更新robot7_account表
		_robot7StockTransactRecordServiceImpl._robot7AccountDaoImpl.UpdateRobotAccountAfterSellOrBuy_all(currentDate)

		/*************************************** 判断整体态势（牛/熊） ***********************************/
		// 判断当前交易日，所有股票的平均价收盘价是否在牛熊线之上。true表示是，false表示否
		var isUpBullShortLine bool = _robot7StockTransactRecordServiceImpl._robot7StockFilterDaoImpl.IsUpBullShortLine(currentDate)
		// 判断当前交易日，所有股票的平均年线是否单调不递减(平均年线只保留小数点后1位)
		//var isAverageMa250NotDecrement bool = _robot7StockTransactRecordServiceImpl._stockTransactionDataAllDaoImpl.IsAverageMa250NotDecrement(currentDate, domain.Robot7Properties_.NotDecrementDateNumber)
		// 判断当前交易日，所有股票的平均年线是否单调不递减(平均年线只保留小数点后2位，并做了平滑处理，时间窗口为20)
		var isAverageMa250NotDecrementSmooth bool = _robot7StockTransactRecordServiceImpl._stockTransactionDataAllDaoImpl.IsAverageMa250NotDecrement_smooth(currentDate, properties.Robot7Properties_.NotDecrementDateNumber)
		// 根据当前交易日，判断所有股票上一周的周线级别的平均K值是否比上上周的平均K值大，true表示是，false表示否
		//var isLastWeekAverageKGreatThanLastTwoWeekAverageK bool = _robot7StockTransactRecordServiceImpl._robot7StockFilterDaoImpl.IsLastWeekAverageKGreatThanLastTwoWeekAverageK(currentDate)
		// 根据当前交易日，判断所有股票上一周的周线级别的平均KD值是否金叉，true表示是，false表示否
		//var isLastWeekAverageKDGolddCross bool = _robot7StockTransactRecordServiceImpl._robot7StockFilterDaoImpl.IsLastWeekAverageKDGoldCross(currentDate)
		// 根据当前交易日，判断所有股票上一周的平均收盘价是否金叉平均MA5，true表示是，false表示否
		//var isLastWeekAverageClosePriceGoldCrossLastWeekAverageMA5 bool = _robot7StockTransactRecordServiceImpl._robot7StockFilterDaoImpl.IsLastWeekAverageClosePriceGoldCrossLastWeekAverageMA5(currentDate)
		// 计算最近n个交易日，上涨家数的百分比的均值，如果大于等于50%则返回true，否则返回false
		//var isUpPercentageGTE50ByDateNumber = _robot7StockTransactRecordServiceImpl._robot7StockFilterDaoImpl.IsUpPercentageGTE50ByDateNumber(currentDate)
		//if isUpPercentageGTE50ByDateNumber == true {
		if isUpBullShortLine == true && isAverageMa250NotDecrementSmooth == true {
			//if isUpBullShortLine == true {
			//if isLastWeekAverageKGreatThanLastTwoWeekAverageK == true {
			//if isLastWeekAverageKDGolddCross == true {
			//if isLastWeekAverageClosePriceGoldCrossLastWeekAverageMA5 == true {
			io.Infoln("当前股票市场，按照牛市处理")

			/****************************************** 加上下面这几句的话，则在牛市中不再交易 ******************************************/
			// 更新robot7_account表的total_assets字段
			//_robot7StockTransactRecordServiceImpl._robot7AccountDaoImpl.UpdateRobotAccountAfterBuyOrSell_all(currentDate)
			//// 打印买卖建议
			//serviceHelper.PrintBuyAndSuggestion(currentDate)
			//continue
			/********************************************************************************************************************/

			/*************************************** 准备数据 ***********************************/
			// 清空robot7_stock_filter表
			_robot7StockTransactRecordServiceImpl._robot7StockFilterDaoImpl.TruncateTableRobotStockFilter()
			// 从stock_transaction_data_all表中向robot7_stock_filter表中插入记录，不包括正在持有的股票
			_robot7StockTransactRecordServiceImpl._robot7StockFilterDaoImpl.InsertBullStockCodeFromStockTransactionDataAll(currentDate)

			/*************************************** 按照条件，过滤股票 ***********************************/
			// 过滤条件：只保留成交量超过VOLUME_MA250或者成交额超过TURNOVER_MA250
			_robot7StockTransactRecordServiceImpl._robot7StockFilterDaoImpl.FilterByVolumeOrTurnoverUp(currentDate)
			// 只保留这个价格区间以内的股票
			_robot7StockTransactRecordServiceImpl._robot7StockFilterDaoImpl.FilterByLessThanStockClosePrice(currentDate, properties.Robot7Properties_.ClosePriceBegin, properties.Robot7Properties_.ClosePriceEnd)
			// 过滤条件：判断用哪根均线作为牛熊线，牛熊线以下的股票都删除。如果在牛熊线以上则准备方差类型和方差值
			_robot7StockTransactRecordServiceImpl._robot7StockFilterDaoImpl.FilterByBiasThreshold_stock(currentDate, properties.Robot7Properties_.BiasThresholdTop, properties.Robot7Properties_.BiasThresholdBottom)
			// 过滤条件：删除上周收盘价死叉周线级别MA5的股票
			//_robot7StockTransactRecordServiceImpl._robot7StockFilterDaoImpl.FilterByLastWeekCLosePriceGoldCrossLastWeekMA5(currentDate)
			// 确定仓位
			io.Infoln("采用固定仓位，仓位为[%d]", properties.Robot7Properties_.MaxHoldStockNumberInBull)

			/************************** 判断使用哪种算法，判断今天是否是交易日 ***************************/
			// 过滤条件：更新robot7_stock_filter表：direction为1；filter_type为交易算法；accumulative_profit_rate累计收益。单位：元
			_robot7StockTransactRecordServiceImpl._robot7StockFilterDaoImpl.UpdateRobotStockFilter_stock(currentDate)
			// 过滤条件：从robot7_stock_filter表中删除那些不是交易日的记录
			_robot7StockTransactRecordServiceImpl._robot7StockFilterDaoImpl.FilterByBuyDate_stock(currentDate)

			// 过滤条件：删除除过权的股票
			_robot7StockTransactRecordServiceImpl._robot7StockFilterDaoImpl.FilterByXr_stock(currentDate, properties.Robot7Properties_.XrDateNumber)
			// 过滤条件：删除一字涨停板
			_robot7StockTransactRecordServiceImpl._robot7StockFilterDaoImpl.FilterByOneWordLimitUp_stock(currentDate)
			// 过滤条件：由于有些涨停板是早上一开盘没多久就涨停的，实际中很难买到，因此这部分股票也删除掉
			_robot7StockTransactRecordServiceImpl._robot7StockFilterDaoImpl.FilterByLimitUp_stock(currentDate)

			/*************************************** 买股票 ******************************************/
			// 买
			_robot7StockTransactRecordServiceImpl._robot7StockTransactRecordDaoImpl.BuyOrSell_stock(currentDate, properties.Robot7Properties_.TransactionStrategyInBull, properties.Robot7Properties_.MaxHoldStockNumberInBull)
			// 更新robot7_account表的total_assets字段
			_robot7StockTransactRecordServiceImpl._robot7AccountDaoImpl.UpdateRobotAccountAfterBuyOrSell_all(currentDate)

			/*************************************** 下面这几行代码在测试中的效果不理想，因此注释掉 ***************************************/
			//var goldCross bool = false
			//// 如果当前交易日所有股票的平均close_price不是金叉ma5，则不做交易
			//goldCross = _robot7StockTransactRecordServiceImpl._robot7StockFilterDaoImpl.IsCurrentStockTransactionDataAllAverageClosePriceGoldCrossMA5(currentDate)
			//if goldCross == false {
			//	io.Infoln("因为当前交易日所有股票的平均close_price不是金叉ma5，所以当前日期不做交易")
			//
			//	// 更新robot7_account表的total_assets字段
			//	_robot7StockTransactRecordServiceImpl._robot7AccountDaoImpl.UpdateRobotAccountAfterBuyOrSell(currentDate)
			//	// 打印买卖建议
			//	serviceHelper.PrintBuyAndSuggestion(currentDate)
			//	continue
			//}
		} else {
			io.Infoln("当前股票市场，所有股票的平均价收盘价在牛熊线之下，或者所有股票的平均年线不是单调不递减，按照熊市处理")

			/****************************************** 加上下面这几句的话，则在熊市中不再交易 ******************************************/
			// 更新robot7_account表的total_assets字段
			_robot7StockTransactRecordServiceImpl._robot7AccountDaoImpl.UpdateRobotAccountAfterBuyOrSell_all(currentDate)
			// 打印买卖建议
			serviceHelper.PrintBuyAndSuggestion(currentDate)
			continue
			/********************************************************************************************************************/

			/*************************************** 准备数据 ***********************************/
			// 清空robot7_stock_filter表
			_robot7StockTransactRecordServiceImpl._robot7StockFilterDaoImpl.TruncateTableRobotStockFilter()
			// 从etf_transaction_data表中向robot7_stock_filter表中插入记录，不包括正在持有的ETF
			_robot7StockTransactRecordServiceImpl._robot7StockFilterDaoImpl.InsertBullStockCodeFromEtfTransactionData(currentDate)

			/*************************************** 按照条件，过滤ETF ***********************************/
			// 只保留这个价格区间以内的ETF
			_robot7StockTransactRecordServiceImpl._robot7StockFilterDaoImpl.FilterByLessThanEtfClosePrice(currentDate, properties.Robot7Properties_.ClosePriceBegin, properties.Robot7Properties_.ClosePriceEnd)
			// 过滤条件：判断用哪根均线作为牛熊线，牛熊线以下的ETF都删除。如果在牛熊线以上则准备相关系数
			_robot7StockTransactRecordServiceImpl._robot7StockFilterDaoImpl.FilterByBiasThreshold_etf(currentDate, properties.Robot7Properties_.BiasThresholdTop, properties.Robot7Properties_.BiasThresholdBottom)
			// 确定仓位（使用动态仓位、熊市时交易ETF），设置参数MaxHoldStockNumberInShort并返回
			_robot7StockTransactRecordServiceImpl._robot7StockFilterDaoImpl.SetMaxHoldStockNumber_etf(currentDate)
			io.Infoln("采用固定仓位，仓位为[%d]", properties.Robot7Properties_.MaxHoldStockNumberInShort)

			/************************** 判断使用哪种算法，判断今天是否是交易日 ***************************/
			// 过滤条件：更新robot7_stock_filter表：direction为1；filter_type为交易算法；accumulative_profit_rate累计收益。单位：元
			_robot7StockTransactRecordServiceImpl._robot7StockFilterDaoImpl.UpdateRobotStockFilter_etf(currentDate)
			// 将robot7_stock_filter表的direction字段改为1
			//_robot7StockTransactRecordServiceImpl._robot7StockFilterDaoImpl.UpdateRobotStockFilterDirection_etf()
			// 过滤条件：从robot7_stock_filter表中删除那些不是交易日的记录
			_robot7StockTransactRecordServiceImpl._robot7StockFilterDaoImpl.FilterByBuyDate_etf(currentDate)

			// 过滤条件：删除MACD死叉的股票
			//_robot7StockTransactRecordServiceImpl._robot7StockFilterDaoImpl.FilterByMacdGoldCross(currentDate)
			// 过滤条件：股票交易日期之前的天数中，如果MACD持续处于金叉状态，则删除
			//_robot7StockTransactRecordServiceImpl._robot7StockFilterDaoImpl.FilterByMacdGoldCrossDateNumber(currentDate, domain.Robot7Config_.MacdGoldDateNumber)
			// 过滤条件：删除上一周，周线级别KD死叉的股票
			//_robot7StockTransactRecordServiceImpl._robot7StockFilterDaoImpl.FilterByLastStockWeekKDGoldCross(currentDate)

			// 过滤条件：删除上一周最低价没有跌破周线级别布林带下轨的记录
			//_robot7StockTransactRecordServiceImpl._robot7StockFilterDaoImpl.FilterByLastLowestPriceDownBullDn(currentDate)

			// 过滤条件：删除除过权的ETF
			_robot7StockTransactRecordServiceImpl._robot7StockFilterDaoImpl.FilterByXr_etf(currentDate, properties.Robot7Properties_.XrDateNumber)
			// 过滤条件：删除一字涨停板
			_robot7StockTransactRecordServiceImpl._robot7StockFilterDaoImpl.FilterByOneWordLimitUp_etf(currentDate)
			// 过滤条件：由于有些涨停板是早上一开盘没多久就涨停的，实际中很难买到，因此这部分ETF也删除掉
			_robot7StockTransactRecordServiceImpl._robot7StockFilterDaoImpl.FilterByLimitUp_etf(currentDate)

			/*************************************** ETF加仓 ******************************************/
			_robot7StockTransactRecordServiceImpl._robot7StockTransactRecordDaoImpl.AddPosition(currentDate, properties.Robot7Properties_.MaxHoldStockNumberInShort)

			/*************************************** 买ETF ******************************************/
			// 买
			_robot7StockTransactRecordServiceImpl._robot7StockTransactRecordDaoImpl.BuyOrSell_etf(currentDate, properties.Robot7Properties_.TransactionStrategyInShort, properties.Robot7Properties_.MaxHoldStockNumberInShort)
			// 更新robot7_account表的total_assets字段
			_robot7StockTransactRecordServiceImpl._robot7AccountDaoImpl.UpdateRobotAccountAfterBuyOrSell_all(currentDate)

			/*************************************** 下面这几行代码在测试中的效果不理想，因此注释掉 ***************************************/
			//var goldCross bool = false
			//// 如果上个星期所有股票的平均KD不是金叉，则不做交易
			//goldCross = _robot7StockTransactRecordServiceImpl._robot7StockFilterDaoImpl.IsLastStockWeekAverageKDGoldCross(currentDate)
			//// 如果上一个交易日所有股票的平均MACD不是金叉，则不做交易
			////goldCross = _robot7StockTransactRecordServiceImpl._robot7StockFilterDaoImpl.IsLastStockTransactionDataAllAverageMACDGoldCross(currentDate)
			//// 如果当前交易日所有股票的平均MACD不是金叉，则不做交易
			////goldCross = _robot7StockTransactRecordServiceImpl._robot7StockFilterDaoImpl.IsCurrentStockTransactionDataAllAverageMACDGoldCross(currentDate)
			//// 如果当前交易日所有股票的平均KD不是金叉，则不做交易
			////goldCross = _robot7StockTransactRecordServiceImpl._robot7StockFilterDaoImpl.IsCurrentStockTransactionDataAllAverageKDGoldCross(currentDate)
			//// 如果当前交易日所有股票的平均close_price不是金叉ma5，则不做交易
			////goldCross = _robot7StockTransactRecordServiceImpl._robot7StockFilterDaoImpl.IsCurrentStockTransactionDataAllAverageClosePriceGoldCrossMA5(currentDate)
			//if goldCross == false {
			//	//io.Infoln("因为上个星期所有股票的平均KD不是金叉，所以当前日期不做交易")
			//	//io.Infoln("因为上一个交易日所有股票的平均MACD不是金叉，所以当前日期不做交易")
			//	io.Infoln("因为当前交易日所有股票的平均MACD不是金叉，所以当前日期不做交易")
			//	//io.Infoln("因为当前交易日所有股票的平均KD不是金叉，所以当前日期不做交易")
			//	//io.Infoln("因为当前交易日所有股票的平均close_price不是金叉ma5，所以当前日期不做交易")
			//
			//	// 更新robot7_account表的total_assets字段
			//	_robot7StockTransactRecordServiceImpl._robot7AccountDaoImpl.UpdateRobotAccountAfterBuyOrSell(currentDate)
			//	// 打印买卖建议
			//	serviceHelper.PrintBuyAndSuggestion(currentDate)
			//	continue
			//}
		}

		/*************************************** 打印买卖建议 ***************************************/
		serviceHelper.PrintBuyAndSuggestion(currentDate)
	}

	io.Infoln("执行根据bias来确定牛熊线的算法结束")
	return nil
}
